package nju.jun.reader.tieba.config;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilderFactory;

import nju.jun.reader.tieba.TiebaListener;
import nju.jun.reader.tieba.data.TiebaNovelLoader;
import nju.jun.reader.tieba.data.TiebaNovelOnLoadListener;
import nju.jun.reader.tieba.model.Tieba;
import nju.jun.reader.tieba.model.TiebaNovel;

import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class TiebaConfigurationLoader {

	private List<TiebaListener> listeners;
	
	private String configPath;
	
	public TiebaConfigurationLoader() {
		listeners = new ArrayList<TiebaListener>();
		listeners.add(new TiebaNovelLoader());
	}

	public TiebaConfigurationLoader(String configurationFilePath) {
		this();
		this.configPath = configurationFilePath;
	}

	public String getConfigPath() {
		return configPath;
	}

	public void setConfigPath(String configPath) {
		this.configPath = configPath;
	}
	
	public void onLoadTiebaNovel(TiebaNovel novel) {
		for (TiebaListener listener : listeners) {
			if (listener instanceof TiebaNovelOnLoadListener) {
				((TiebaNovelOnLoadListener) listener).onLoad(novel);
			}
		}
	}

	public synchronized void parse() throws Exception {
		Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(configPath));
		NodeList nodes = doc.getElementsByTagName(TiebaConfigurationTags.NOVEL);
		if (nodes == null) {
			return;
		}
		for (int i = 0; i < nodes.getLength(); i++) {
			Element element = (Element) nodes.item(i);
			
			// construct TiebaNovel instance
			TiebaNovel novel = new TiebaNovel();
			novel.setTiebaName(getNodeValue(element, TiebaConfigurationTags.TIEBA_NAME));
			novel.setNovelName(getNodeValue(element, TiebaConfigurationTags.NOVEL_NAME));
			try {
				novel.setOnTop(Boolean.parseBoolean(getNodeValue(element, TiebaConfigurationTags.ON_TOP)));
			} catch (Exception e) {
				novel.setOnTop(true);
			}
//			try {
//				novel.setChapter(Integer.parseInt(getNodeValue(element, TiebaConfigurationTags.CHAPTER)));
//			} catch (Exception e) {
//				novel.setChapter(1);
//			}
			novel.setAuthor(getNodeValue(element, TiebaConfigurationTags.AUTHOR));
			
			// trigger event to load current max volume no and chapter no
			onLoadTiebaNovel(novel);
			
			Tieba.instance().addNovel(novel);
		}
	}
	
	private String getNodeValue(Element elem, String tag) {
		NodeList nodes = elem.getElementsByTagName(tag);
		if (nodes == null) {
			return null;
		}
		Element child = (Element) nodes.item(0);
		String rtn = null;
		try {
			rtn = child.getTextContent();
		} catch (DOMException e) {
			return null;
		}
		return rtn;
	}

}
